//
//  BKODCalendarView.m
//  CanlendarTest
//
//  Created by yons on 17/2/13.
//  Copyright © 2017年 马乾征. All rights reserved.
//

#import "BKODCalendarView.h"
#import "BK_Calendar_WeekdayView.h"
#import "BK_Calendar_Model.h"
#import "BK_Calendar_ViewCell.h"



/**
    calendar main view
 */

@interface BKODCalendarView ()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property(nonatomic, strong)BK_Calendar_WeekdayView *weekdayView;
@property(nonatomic, strong)UICollectionView *collectionView;
@property(nonatomic, strong)NSCalendar *calendar;
@property(nonatomic, strong)NSDateFormatter *dateFormatter;
@property(nonatomic, strong)NSMutableArray <SectionModel *> *sectionArray;
@property(nonatomic, assign)NSInteger weekOfMonth;
@end

@implementation BKODCalendarView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self initialize];
    }
    return self;
}

- (void)initialize
{
    self.backgroundColor = [UIColor whiteColor];
    
    _sectionArray = [NSMutableArray array];
    _dateFormatter = [[NSDateFormatter alloc] init];
    [_dateFormatter setDateFormat:@"yyyy-MM-dd"];
    _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    
    _minimumDate = [_calendar od_firstDayOfMonth:[NSDate date]];
    _maximumDate = [_calendar od_lastDayOfMonth:[NSDate date]];
    _currentPage = _minimumDate;
    
    _calendarHeaderView = [[BK_Calendar_HeaderView alloc] initWithFrame:CGRectZero];
    _calendarHeaderView.backgroundColor = [UIColor colorWithRed:0.93 green:0.93 blue:0.93 alpha:1];
    [_calendarHeaderView setTitle:[_calendarHeaderView.formatter stringFromDate:_currentPage]];
    [self addSubview:_calendarHeaderView];
    
    _weekdayView = [[BK_Calendar_WeekdayView alloc] initWithFrame:CGRectZero];
    [self addSubview:_weekdayView];
    
    _collectionView = ({
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
        UICollectionView *collection = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
        collection.dataSource = self;
        collection.delegate = self;
        collection.backgroundColor = [UIColor clearColor];
        collection.bounces = YES;
        collection.pagingEnabled = YES;
        collection.showsHorizontalScrollIndicator = NO;
        collection.showsVerticalScrollIndicator = NO;
        collection.delaysContentTouches = NO;
        collection.canCancelContentTouches = YES;
        collection.allowsMultipleSelection = NO;
        collection.scrollEnabled = NO;
        [collection registerClass:[BK_Calendar_ViewCell class] forCellWithReuseIdentifier:@"calendarCell"];
        collection;
    });
    [self addSubview:_collectionView];
    
    [self makeConstraints];
}

- (void)makeConstraints
{
    _calendarHeaderView.translatesAutoresizingMaskIntoConstraints = NO;
    NSLayoutConstraint *headerViewTopConstraint = [NSLayoutConstraint constraintWithItem:_calendarHeaderView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1 constant:0];
    NSLayoutConstraint *headerViewLeftConstraint = [NSLayoutConstraint constraintWithItem:_calendarHeaderView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
    NSLayoutConstraint *headerViewRightConstraint = [NSLayoutConstraint constraintWithItem:_calendarHeaderView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1 constant:0];
    NSLayoutConstraint *headerViewHeightConstraint = [NSLayoutConstraint constraintWithItem:_calendarHeaderView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:30];
    [self addConstraints:@[headerViewTopConstraint, headerViewLeftConstraint, headerViewRightConstraint, headerViewHeightConstraint]];
    
    _weekdayView.translatesAutoresizingMaskIntoConstraints = NO;
    NSLayoutConstraint *weekdayViewTopConstraint = [NSLayoutConstraint constraintWithItem:_weekdayView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_calendarHeaderView attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
    NSLayoutConstraint *weekdayViewLeftConstraint = [NSLayoutConstraint constraintWithItem:_weekdayView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
    NSLayoutConstraint *weekdayViewRightConstraint = [NSLayoutConstraint constraintWithItem:_weekdayView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1 constant:0];
    NSLayoutConstraint *weekdayViewHeightConstraint = [NSLayoutConstraint constraintWithItem:_weekdayView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:30];
    [self addConstraints:@[weekdayViewTopConstraint, weekdayViewLeftConstraint, weekdayViewRightConstraint, weekdayViewHeightConstraint]];
    
    
    _collectionView.translatesAutoresizingMaskIntoConstraints = NO;
    NSLayoutConstraint *collectionTopConstraint = [NSLayoutConstraint constraintWithItem:_collectionView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_weekdayView attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
    NSLayoutConstraint *collectionLeftConstraint = [NSLayoutConstraint constraintWithItem:_collectionView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
    NSLayoutConstraint *collectionRightConstraint = [NSLayoutConstraint constraintWithItem:_collectionView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1 constant:0];
    NSLayoutConstraint *collectionBottomConstraint = [NSLayoutConstraint constraintWithItem:_collectionView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:-30];
    
    [self addConstraints:@[collectionTopConstraint, collectionLeftConstraint, collectionRightConstraint, collectionBottomConstraint]];
    
}

- (void)creatSectionData{
    
    if (_sectionArray.count) {
        [_sectionArray removeAllObjects];
    }
    
    NSDate *minDate = [_calendar od_firstDayOfMonth:_minimumDate];
    NSDate *maxDate = [_calendar od_lastDayOfMonth:_maximumDate];
    NSInteger numberOfMonths = [_calendar od_numberOfMonthFromMonth:minDate toMonth:maxDate] + 1;
    for (int i = 0; i < numberOfMonths; i++) {
        
        SectionModel *sm = [[SectionModel alloc] init];
        sm.userInfo = [_calendar od_dateWithDifferenceMonth:i atDate:minDate];
        [_sectionArray addObject:sm];
    }
}



#pragma mark collection delegate & dataSource

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{

    CGFloat width = CGRectGetWidth(collectionView.frame);
    CGFloat height = CGRectGetHeight(collectionView.frame);
    
    SectionModel *sm = _sectionArray[indexPath.section];
    NSDate *lastDate = [_calendar od_lastDayOfMonth:sm.userInfo];
    NSDateComponents *dateComponents = [_calendar od_dateComponents:lastDate];
    NSInteger numberOfRows = dateComponents.weekOfMonth;
    return CGSizeMake(width / 7, height / numberOfRows);
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
    return 0;
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
    return 0;
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    if (!_sectionArray.count) {
        [self creatSectionData];
    }
    return _sectionArray.count;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    SectionModel *sm = _sectionArray[section];
    NSDate *lastDayInMonth = [_calendar od_lastDayOfMonth:sm.userInfo];
    NSDateComponents *dateComponents = [_calendar od_dateComponents:lastDayInMonth];
    return dateComponents.weekOfMonth * 7;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    BK_Calendar_ViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"calendarCell" forIndexPath:indexPath];
    return cell;
}

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSDate *itemDate = [self dateWithIndexPath:indexPath];
    BK_Calendar_Model *obj = [[BK_Calendar_Model alloc] init];
    if (itemDate != nil) {
        
        NSString *title;
        if (self.delegate && [self.delegate respondsToSelector:@selector(calendar:titleForDate:)]) {
            title = [self.delegate calendar:self titleForDate:itemDate];
        }
        NSString *subTitle;
        if (self.delegate && [self.delegate respondsToSelector:@selector(calendar:subtitleForDate:)]) {
            subTitle = [self.delegate calendar:self subtitleForDate:itemDate];
        }
        
        obj.date = itemDate;
        obj.title = title;
        obj.subTitle = subTitle;
    }
    BK_Calendar_ViewCell *calendarCell = (BK_Calendar_ViewCell *)cell;
    [calendarCell fillData:obj];
    
    //重用选中处理
    NSIndexPath *selectIndexPath = [collectionView indexPathsForSelectedItems].firstObject;
    if ([selectIndexPath isEqual:indexPath]) {
        [calendarCell select1:NO];
    }else{
        [calendarCell unselect1:NO];
    }
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{

    BK_Calendar_ViewCell *cell = (BK_Calendar_ViewCell *)[collectionView cellForItemAtIndexPath:indexPath];
    [cell select1:YES];
    
    NSDate *date = [self dateWithIndexPath:indexPath];
    _selectedDate = date;
    if (self.delegate && [self.delegate respondsToSelector:@selector(calendar:didSelectDate:)]) {
        [self.delegate calendar:self didSelectDate:date];
    }
}

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{
    BK_Calendar_ViewCell *cell = (BK_Calendar_ViewCell *)[collectionView cellForItemAtIndexPath:indexPath];
    [cell unselect1:YES];
}

- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSDate *shouldSelectDate = [self dateWithIndexPath:indexPath];

    if (!shouldSelectDate) {
        return NO;
    }
    
    if (self.delegate && [self.delegate respondsToSelector:@selector(calendar:shouldSelectDate:)]) {
        return [self.delegate calendar:self shouldSelectDate:shouldSelectDate];
    }
    return YES;
}


#pragma mark external methods

- (void)setCurrentPage:(NSDate *)currentPage
{
    _currentPage = currentPage;
    [_calendarHeaderView setTitle:[_calendarHeaderView.formatter stringFromDate:currentPage]];
    NSInteger numberOfMonth = [_calendar od_numberOfMonthFromMonth:_minimumDate toMonth:currentPage];
    [_collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:numberOfMonth] atScrollPosition:UICollectionViewScrollPositionTop animated:NO];
}

- (void)reloadData
{
    [_collectionView reloadData];
}

- (void)selectDate:(NSDate *)date
{
    NSIndexPath *indexPath = [self indexPathWithDate:date];
    [self selectIndexPath:indexPath];
    
}

#pragma mark private methods
- (NSIndexPath *)indexPathWithDate:(NSDate *)date
{

    NSDateComponents *dateCompontents = [_calendar od_dateComponents:date];
    
    NSInteger section = [_calendar od_numberOfMonthFromMonth:_minimumDate toMonth:date];
    NSInteger row = (dateCompontents.weekOfMonth - 1) * 7 - 1 + dateCompontents.weekday;
    
    return [NSIndexPath indexPathForRow:row inSection:section];
}

- (NSDate *)dateWithIndexPath:(NSIndexPath *)indexPath
{
    SectionModel *sm = _sectionArray[indexPath.section];
    
    NSDate *fristDayInMonth = [_calendar od_firstDayOfMonth:sm.userInfo];
    NSDate *lastDayInMonth  = [_calendar od_lastDayOfMonth:sm.userInfo];
    
    NSDate *usedMinDate = fristDayInMonth.copy;
    NSDate *usedMaxDate = lastDayInMonth.copy;
    if (indexPath.section == 0) {
        usedMinDate = [_calendar od_numberOfDaysFromDate:usedMinDate toDate:_minimumDate] > 0 ? _minimumDate : usedMinDate;
    }
    if (indexPath.section == _sectionArray.count - 1) {
        usedMaxDate = [_calendar od_numberOfDaysFromDate:usedMaxDate toDate:_maximumDate] > 0 ? usedMaxDate : _maximumDate;
    }
    NSDateComponents *uMinCompontents = [_calendar od_dateComponents:usedMinDate];
    NSDateComponents *uMaxCompontents = [_calendar od_dateComponents:usedMaxDate];
    
    NSInteger minNoDateCount = (uMinCompontents.weekOfMonth - 1) * 7 + uMinCompontents.weekday - 1;
    if (indexPath.row < minNoDateCount) {
        return nil;
    }
    NSInteger maxNoDateCount = (uMaxCompontents.weekOfMonth - 1) * 7 + uMaxCompontents.weekday - 1;
    if (indexPath.row > maxNoDateCount) {
        return nil;
    }
    
    NSDate *itemDate = [_calendar od_dateWithDifferenceDays:indexPath.row - minNoDateCount atDate:usedMinDate];
    return itemDate;
}

- (void)selectIndexPath:(NSIndexPath *)indexPath
{
    [_collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];
    [self collectionView:_collectionView didSelectItemAtIndexPath:indexPath];
}
@end
